﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using RemoteTestRunner.BusinessLogic;
using RemoteTestRunner.BusinessLogic.Views;
using RemoteTestRunner.Contracts;
using RemoteTestRunner.FormsUI.Presenters;

namespace RemoteTestRunner.FormsUI
{
    /// <summary>
    /// This is the main view for the Remote Test Runner application.
    /// </summary>
    public partial class Runner : Form, ITestRunnerView, IApplicationNavigationView
    {
        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="Runner"/> class.
        /// </summary>
        public Runner()
        {
            InitializeComponent();
        }

        #endregion

        #region Event Handlers

        /// <summary>
        /// Handles the FormClosed event of the Runner control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.FormClosedEventArgs"/> instance containing the event data.</param>
        private void Runner_FormClosed(object sender, FormClosedEventArgs e)
        {
            _closedListener.Invoke(sender, e);
        }

        /// <summary>
        /// Handles the Load event of the Runner control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void Runner_Load(object sender, EventArgs e)
        {
            mnuDeleteTestRunHistoryItem.Click += _deleteTestResultsListener;
            ctxDeleteTestRunHistoryItem.Click += _deleteTestResultsListener;

            cboProjects.SelectionChangeCommitted += _projectSelectedListener;
            cboTests.SelectionChangeCommitted += _testSelectedListener;
            lstRunHistory.SelectedValueChanged += _testResultSelectedListener;
            mnuFileSendEmail.Click += _emailTestResultsListener;

            mnuToolsConfigureTests.Click += _editTestsRequestedListener;
            toolConfigureTests.Click += _editTestsRequestedListener;

            mnuToolsConfigureTestProjects.Click += _editProjectsRequestedListener;
            toolConfigureTestProjects.Click += _editProjectsRequestedListener;

            mnuToolsOptions.Click += _editOptionsRequestedListener;
            //this.FormClosed += _closedListener;
            //mnuTestRun.Click += _runTestListener;

            if (!File.Exists(RtrSettings.DataPath))
            {
                MessageBox.Show(
                    "You must select a data file to work with before continuing.",
                    "Select Data File",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);

                _editOptionsRequestedListener(sender, e);
                //DisplayOptionsDialog();
            }
            //else
            //{
            //    // Setup the appropriate test runner facade (i.e. will we be running from the local
            //    // client or the server?
            //    //InitializeServiceFacade();
            //}

            // Set default value of test filter
            toolFilterTests.Checked = RtrSettings.FilterTests;

            //var index = 1;
            //foreach (Bitmap item in imgIcons.Images)
            //{
            //    item.Save(@"c:\" + index + ".bmp");
            //    index++;
            //}
        }

        /// <summary>
        /// Opens an existing test results file for viewing.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void mnuFileOpen_Click(object sender, EventArgs e)
        {
            OpenTestResultsFile();
        }

        /// <summary>
        /// Handles the Click event of the mnuFileExit control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void mnuFileExit_Click(object sender, EventArgs e)
        {
            Close();
        }

        /// <summary>
        /// Hides/shows the inputs panel.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void mnuToolsHideShowInputs_Click(object sender, EventArgs e)
        {
            splitContainerSub.Panel1Collapsed = !splitContainerSub.Panel1Collapsed;
            splitContainerMain.Panel1Collapsed = splitContainerSub.Panel1Collapsed;

            toolToggleInputs.Checked = !splitContainerSub.Panel1Collapsed;
            mnuToolsHideShowInputs.Checked = !splitContainerSub.Panel1Collapsed;
        }

        /// <summary>
        /// Filters out non-data-driven tests.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void mnuToolsFilterTests_Click(object sender, EventArgs e)
        {
            toolFilterTests.Checked = !toolFilterTests.Checked;
            mnuToolsFilterTests.Checked = toolFilterTests.Checked;

            _testsFilteredListener.Invoke(this, new GenericEventArgs<bool>(toolFilterTests.Checked));
        }

        /// <summary>
        /// Handles the Click event of the mnuTestRun control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void mnuTestRun_Click(object sender, EventArgs e)
        {
            RunTest();
        }

        /// <summary>
        /// Displays the selected data source.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void ViewDataSource_Click(object sender, EventArgs e)
        {
            var sourceName = ((ToolStripMenuItem)sender).Name;

            _dataSourceSelectedListener(sender, new GenericEventArgs<string>(sourceName));
        }

        /// <summary>
        /// Handles the Click event of the mnuHelpAbout control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void mnuHelpAbout_Click(object sender, EventArgs e)
        {
            using (var aboutDlg = new About())
            {
                aboutDlg.ShowDialog(this);
            }
        }

        /// <summary>
        /// Displays the help file.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void mnuHelpTopics_Click(object sender, EventArgs e)
        {
            Process.Start("RTRDocs.chm");
        }

        /// <summary>
        /// Copies details for the selected test results to the Clipboard.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void mnuTestCopyTestDetails_Click(object sender, EventArgs e)
        {
            //string text = string.Empty;
            //int row;

            //foreach (ListViewItem lvItem in lvResults.SelectedItems)
            //{
            //    foreach (TestResultInfo item in _testResult.TestResults)
            //    {
            //        if (item.ExecutionId == lvItem.Tag.ToString())
            //        {
            //            text += item.ToString() + "\r\n\r\n========================\r\n\r\n";

            //            break;
            //        }
            //        else
            //        { // Search in any data-driven results
            //            row = 0;

            //            foreach (TestResultInfo ddItem in item.DataDrivenResults)
            //            {
            //                row++;

            //                if (ddItem.ExecutionId == lvItem.Tag.ToString())
            //                {
            //                    text += string.Format("[row: {0}]", row) +
            //                        ddItem.ToString() + "\r\n\r\n========================\r\n\r\n";

            //                    break;
            //                }
            //            }
            //        }
            //    }
            //}

            //Clipboard.SetText(text);
        }

        ///// <summary>
        ///// Enables/disables form options based upon the current state.
        ///// </summary>
        ///// <param name="sender">The source of the event.</param>
        ///// <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param>
        //private void contextMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        //{
        //    UpdateOptions();
        //}

        ///// <summary>
        ///// Enables/disables form options based upon the current state.
        ///// </summary>
        ///// <param name="sender">The source of the event.</param>
        ///// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        //private void mnuTest_DropDownOpening(object sender, EventArgs e)
        //{
        //    UpdateOptions();
        //}

        /// <summary>
        /// Validates items that are attempting to be "dragged-n-dropped" on the ListView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.DragEventArgs"/> instance containing the event data.</param>
        /// <remarks>The item being dragged must be a file with a ".trx" extension.</remarks>
        private void lvResults_DragEnter(object sender, DragEventArgs e)
        {
            var dropAllowed = false;

            if (e.Data.GetDataPresent("FileNameW"))
            {
                var filename = ((string[])e.Data.GetData("FileNameW"))[0];

                dropAllowed = (string.Compare(Path.GetExtension(filename), ".trx", true) == 0);
            }

            e.Effect = dropAllowed ? DragDropEffects.Copy : DragDropEffects.None;
        }

        /// <summary>
        /// Opens the item being "dragged-n-dropped" on the ListView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.DragEventArgs"/> instance containing the event data.</param>
        /// <remarks>The item being dropped must be a file with a ".trx" extension.</remarks>
        private void lvResults_DragDrop(object sender, DragEventArgs e)
        {
            TestFile = ((string[])e.Data.GetData("FileNameW"))[0];
            _loadTestFileRequested(sender, e);
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Setups the data source menu.
        /// </summary>
        //private void SetupDataSourceMenu()
        //{
        //    ToolStripMenuItem menuItem;
        //    // Clear out the sub-menus
        //    mnuTestViewDataSource.DropDown.Items.Clear();
        //    TestInfo testInfo = _serviceFacade.GetTestRow((int)cboTests.SelectedValue);
        //    List<DataSourceInfo> dsInfo = _serviceFacade.GetDataSources(testInfo.ConfigPath);
        //    if (dsInfo != null)
        //    {
        //        foreach (DataSourceInfo item in dsInfo)
        //        {
        //            string targetDataSourcePath;
        //            if (!string.IsNullOrEmpty(item.DataSourceBaseUri))
        //            {
        //                targetDataSourcePath = item.DataSourceBaseUri;
        //            }
        //            else
        //            {
        //                targetDataSourcePath = item.DataSourcePath;
        //            }
        //            // Populate Test->View Data Source menu
        //            menuItem = new ToolStripMenuItem(item.ConnectionStringName, null, new EventHandler(ViewDataSource_Click), item.Name);
        //            menuItem.Tag = targetDataSourcePath;
        //            mnuTestViewDataSource.DropDown.Items.Add(menuItem);
        //        }
        //    }
        //    // Disable the menu option if there are no data sources
        //    mnuTestViewDataSource.Enabled = (mnuTestViewDataSource.DropDown.Items.Count > 0);
        //}
        /// <summary>
        /// Loads the results XML file and displays the formatted test results.
        /// </summary>
        /// <param name="testResult">The test results to be displayed.</param>
        public void DisplayTestResults(TestResult testResult)
        {
            lvResults.Items.Clear();

            if (testResult == null)
            {
                var presenter = new DetailedResultsPresenter(detailResults1, null);
                presenter.Start();

                Text = "Remote Test Runner";
                lblTotalCount.Text = "0";
                lblTotalExecuted.Text = "0";
                lblTotalPassed.Text = "0";
                lblTotalFailed.Text = "0";
                lblTotalTimedOut.Text = "0";
                lblTotalInconclusive.Text = "0";

                SetStatusMessage("Ready");
            }
            else
            {
                var outcome = new Dictionary<string, int>();
                ListViewItem lvItem;

                // Display the filename
                Text = string.Format("Remote Test Runner - [{0}]", Path.GetFileNameWithoutExtension(testResult.Path));

                outcome.Add("Passed", 0);
                outcome.Add("Failed", 0);
                outcome.Add("Inconclusive", 0);
                outcome.Add("Skipped", 0);

                foreach (var resultInfo in testResult.TestResults)
                {
                    lvItem = new ListViewItem(
                        new[]
                            {
                                resultInfo.MethodName,
                                resultInfo.Message
                            },
                        lvResults.Groups[resultInfo.Outcome]) { Tag = resultInfo.ExecutionId };

                    // Store the Execution ID

                    // Display an icon for each test
                    switch (resultInfo.Outcome)
                    {
                        case "Passed":
                        case "Failed":
                            lvItem.ImageKey = resultInfo.Outcome;
                            break;
                        default:
                            lvItem.ImageKey = "Inconclusive";
                            break;
                    }

                    // Display the detailed results in the ToolTip
                    lvItem.ToolTipText = resultInfo.ToString();

                    // If the test failed, display the item in a different color/weight
                    if (resultInfo.Outcome == "Failed")
                    {
                        lvItem.ForeColor = Color.Red;
                    }

                    lvResults.Items.Add(lvItem);

                    if (resultInfo.IsDataDriven)
                    {
                        var ddTestCount = 0;

                        // Add sub-rows for data-driven test results
                        foreach (var ddResultInfo in resultInfo.DataDrivenResults)
                        {
                            ddTestCount++;

                            lvItem = new ListViewItem(
                                new[]
                                    {
                                        string.Format("     [row: {0}]", ddTestCount), //ddResultInfo.MethodName,
                                        ddResultInfo.Message
                                    },
                                lvResults.Groups[resultInfo.Outcome])
                                         {
                                             Tag = ddResultInfo.ExecutionId,
                                             ImageKey = ddResultInfo.Outcome,
                                             ToolTipText = ddResultInfo.ToString()
                                         };

                            // Store the Execution ID

                            // Display an icon for each test

                            // Display the detailed results in the ToolTip

                            // If the test failed, display the item in a different color/weight
                            if (ddResultInfo.Outcome == "Failed")
                            {
                                lvItem.ForeColor = Color.Red;
                            }

                            lvResults.Items.Add(lvItem);
                        }
                    }
                }

                // Display summary results
                lblTotalCount.Text = testResult.TotalCount.ToString("N0");
                lblTotalExecuted.Text = testResult.TotalExecuted.ToString("N0");
                lblTotalPassed.Text = testResult.TotalPassed.ToString("N0");
                lblTotalFailed.Text = testResult.TotalFailed.ToString("N0");
                lblTotalTimedOut.Text = testResult.TotalTimedOut.ToString("N0");
                lblTotalInconclusive.Text = testResult.TotalInconclusive.ToString("N0");

                // Set status message
                if (testResult.TotalExecuted == testResult.TotalPassed)
                {
                    SetStatusMessage("All tests passed", Color.LightGreen);
                }
                else if ((testResult.TotalFailed > 0) || (testResult.TotalTimedOut > 0))
                {
                    SetStatusMessage("One or more tests failed and/or timed out", Color.LightCoral);
                }
                else if (outcome["Inconclusive"] > 0)
                {
                    SetStatusMessage("One or more tests were inconclusive", Color.LightYellow);
                }

                var presenter = new DetailedResultsPresenter(detailResults1, testResult);
                presenter.Start();
            }
            UpdateOptions();
        }

        /// <summary>
        /// Get the appropriate service facade based on whether we're planning on running
        /// the tests locally or on a server (e.g. build server).
        /// </summary>
        //private void InitializeServiceFacade()
        //{
        //    if (RtrSettings.UseRunnerService)
        //    {
        //        // Run on server
        //        _serviceFacade = ServiceFactory.GetServiceObject(
        //            RtrSettings.RunnerServiceUrl,
        //            RtrSettings.TestTimeoutSeconds);
        //    }
        //    else
        //    {
        //        // Run on local client
        //        _serviceFacade = ServiceFactory.GetServiceObject(ServiceType.ClientService);
        //    }
        //    _rtrServiceSettingsChangedListener(this, EventArgs.Empty);
        //    _reloadProjectsListener(this, EventArgs.Empty);
        //}
        /// <summary>
        /// Enables/disables form options based upon the current state.
        /// </summary>
        private void UpdateOptions()
        {
            mnuTestRun.Enabled = cboTests.SelectedIndex >= 0;
            toolRunTest.Enabled = mnuTestRun.Enabled;

            mnuTestCopyTestDetails.Enabled = (lvResults.SelectedItems.Count > 0);

            ctxDeleteTestRunHistoryItem.Enabled = lstRunHistory.SelectedItems.Count > 0;
            mnuDeleteTestRunHistoryItem.Enabled = lstRunHistory.SelectedItems.Count > 0;

            //mnuFileSendEmail.Enabled = _testResult != null;
            //toolSendNotification.Enabled = _testResult != null;

            mnuTestViewDataSource.Enabled = cboTests.SelectedIndex >= 0;
        }

        /// <summary>
        /// Runs the selected test.
        /// </summary>
        private void RunTest()
        {
            if (MessageBox.Show("Run selected test?", "Run Test", MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==
                DialogResult.Yes)
            {
                //Cursor.Current = Cursors.WaitCursor;
                _runTestListener(this, EventArgs.Empty);
            }
        }

        /// <summary>
        /// Gets the checked nodes.
        /// </summary>
        /// <returns>An IList of all the checked nodes.</returns>
        private List<string> GetCheckedNodes()
        {
            var returnList = new List<string>();
            foreach (TreeNode root in tvwClassesAndMethods.Nodes)
            {
                if (root.Checked)
                {
                    // root is checked.  Return an empty list so all tests will run.
                }
                else
                {
                    foreach (TreeNode classNode in root.Nodes)
                    {
                        if (classNode.Checked)
                        {
                            // Add whole class
                            returnList.Add(classNode.Text);
                        }
                        else
                        {
                            foreach (TreeNode methodNode in classNode.Nodes)
                            {
                                if (methodNode.Checked)
                                {
                                    returnList.Add(classNode.Text + "." + methodNode.Text);
                                }
                            }
                        }
                    }
                }
            }

            return returnList;
        }

        /// <summary>
        /// Sets the status message.
        /// </summary>
        /// <param name="message">The message to be displayed.</param>
        private void SetStatusMessage(string message)
        {
            SetStatusMessage(message, SystemColors.Control);
            UpdateOptions();
        }

        /// <summary>
        /// Sets the status message.
        /// </summary>
        /// <param name="message">The message to be displayed.</param>
        /// <param name="backColor">The color to set the status bar background color to.</param>
        private void SetStatusMessage(string message, Color backColor)
        {
            ssStatus.Items[0].Text = message;
            ssStatus.BackColor = backColor;
            Application.DoEvents();
            UpdateOptions();
        }

        /// <summary>
        /// Opens an existing test results file.
        /// </summary>
        private void OpenTestResultsFile()
        {
            openFileDialog1.CheckFileExists = true;
            openFileDialog1.CheckPathExists = true;
            openFileDialog1.DefaultExt = ".trx";
            openFileDialog1.Filter = "Test Result Files (*.trx)|*.trx|All Files (*.*)|*.*";
            openFileDialog1.FilterIndex = 0;
            openFileDialog1.InitialDirectory = RtrSettings.WorkingFolder;
            openFileDialog1.Multiselect = false;
            openFileDialog1.Title = "Select Test Result File";

            if (openFileDialog1.ShowDialog(this) == DialogResult.OK)
            {
                TestFile = openFileDialog1.FileName;
                _loadTestFileRequested(this, EventArgs.Empty);
            }
        }

        #endregion

        #region Event Handler Declarations

        private EventHandler _closedListener;
        private EventHandler _copyTestResultsToClipBoard;
        private EventHandler<GenericEventArgs<string>> _dataSourceSelectedListener;
        private EventHandler _deleteTestResultsListener;
        private EventHandler _editOptionsRequestedListener;
        private EventHandler _editProjectsRequestedListener;
        private EventHandler _editTestsRequestedListener;
        private EventHandler _emailTestResultsListener;
        private EventHandler _loadPreviousTestRunsListener;
        private EventHandler _loadTestFileRequested;
        private EventHandler _projectSelectedListener;
        private EventHandler _runTestListener;
        private EventHandler _testResultSelectedListener;
        private EventHandler _testSelectedListener;
        private EventHandler<GenericEventArgs<bool>> _testsFilteredListener;

        #endregion

        #region IApplicationNavigationView Members

        public void SubscribeEditOptionsRequested(EventHandler listener)
        {
            _editOptionsRequestedListener = listener;
        }

        public void SubscribeEditProjectsRequested(EventHandler listener)
        {
            _editProjectsRequestedListener = listener;
        }

        public void SubscribeEditTestsRequested(EventHandler listener)
        {
            _editTestsRequestedListener = listener;
        }

        #endregion

        #region ITestRunnerView Members

        public List<TestResultSummary> SelectedTestResults
        {
            get
            {
                var selectedResults = new List<TestResultSummary>();
                foreach (var selectedItem in lstRunHistory.SelectedItems)
                {
                    selectedResults.Add(selectedItem as TestResultSummary);
                }
                return selectedResults;
            }
            set
            {
                if (value.Count == 1)
                {
                    lstRunHistory.SelectedItems.Clear();
                    //lstRunHistory.SelectedItem = value[0];
                    foreach (TestResultSummary result in lstRunHistory.Items)
                    {
                        if (result.TestRunId == value[0].TestRunId)
                        {
                            lstRunHistory.SelectedItem = result;
                            break;
                        }
                    }
                }
                else
                {
                    throw new ArgumentException("Only a 1 item list of values is permitted.");
                }

                //// Select the run that just completed.
                UpdateOptions();
            }
        }

        public void SetTestResultHistory(IList<TestResultSummary> results)
        {
            lstRunHistory.DataSource = results;
            lstRunHistory.DisplayMember = "TestRunName";
            UpdateOptions();
        }

        public void SetTestClassAndMethods(IList<TestClass> classesAndMethods)
        {
            tvwClassesAndMethods.Nodes.Clear();

            // Add a root node that is checked by default.
            var rootNode = tvwClassesAndMethods.Nodes.Add("All Classes and Methods");
            rootNode.ImageKey = "All";
            rootNode.SelectedImageKey = "All";

            // Fill the selection tree view with the classes and methods
            if (classesAndMethods != null)
            {
                // Add the hierarchial classes and methods
                foreach (var testClass in classesAndMethods)
                {
                    var classNode = rootNode.Nodes.Add(testClass.Name);

                    classNode.ImageKey = "Class";
                    classNode.SelectedImageKey = "Class";

                    foreach (var testMethod in testClass.TestMethods)
                    {
                        TreeNode methodNode;

                        if (testMethod.DataDriven)
                        {
                            methodNode = classNode.Nodes.Add(testMethod.Name);
                            methodNode.ImageKey = "DataDrivenTest";
                            methodNode.SelectedImageKey = "DataDrivenTest";
                        }
                        else
                        {
                            methodNode = classNode.Nodes.Add(testMethod.Name);
                            methodNode.ImageKey = "Test";
                            methodNode.SelectedImageKey = "Test";
                        }
                    }
                }

                tvwClassesAndMethods.ExpandAll();
                rootNode.EnsureVisible();
            }
            UpdateOptions();
        }

        public List<string> GetTestsToRun()
        {
            return GetCheckedNodes();
        }

        public void SubscribeTestResultSelected(EventHandler listener)
        {
            _testResultSelectedListener = listener;
        }

        public void SubscribeRunTest(EventHandler listener)
        {
            _runTestListener = listener;
        }

        public void SubscribeEmailTestResults(EventHandler listener)
        {
            _emailTestResultsListener = listener;
        }

        public void SubscribeProjectSelected(EventHandler listener)
        {
            _projectSelectedListener = listener;
        }

        public void SubscribeTestSelected(EventHandler listener)
        {
            _testSelectedListener = listener;
        }

        public void SubscribeTestsFiltered(EventHandler<GenericEventArgs<bool>> listener)
        {
            _testsFilteredListener = listener;
        }

        public void SubscribeDeleteTestResults(EventHandler listener)
        {
            _deleteTestResultsListener = listener;
        }

        public TestResultSummary TestResultSummary
        {
            get { return lstRunHistory.SelectedItem as TestResultSummary; }
            set
            {
                lstRunHistory.SelectedItem = value;
                UpdateOptions();
            }
        }

        public DataRowView Test
        {
            get { return cboTests.SelectedItem as DataRowView; }
            set
            {
                cboTests.SelectedItem = value;
                UpdateOptions();
            }
        }

        public DataRowView Project
        {
            get { return cboProjects.SelectedItem as DataRowView; }
            set
            {
                cboProjects.SelectedItem = value;
                UpdateOptions();
            }
        }

        public void SetProjects(DataView projects)
        {
            cboProjects.DataSource = projects;
            if (projects != null && projects.Count > 0)
            {
                cboProjects.DisplayMember = "Name";
                cboProjects.ValueMember = "ID";
            }
            UpdateOptions();
        }

        public void SetTests(DataView tests)
        {
            cboTests.DataSource = tests;
            if (tests != null && tests.Count > 0)
            {
                cboTests.DisplayMember = "Name";
                cboTests.ValueMember = "ID";
            }
            UpdateOptions();
        }

        public void SubscribeClosed(EventHandler listener)
        {
            _closedListener = listener;
        }

        public void SetTestInfo(TestInfo info)
        {
            sourceTestInfo.DataSource = info;
            UpdateOptions();
        }

        //public void SetTestResult(TestResult result)
        //{
        //    sourceTestResult.DataSource = result;
        //    UpdateOptions();
        //}

        public void SubscribeLoadPreviousTestRuns(EventHandler listener)
        {
            _loadPreviousTestRunsListener = listener;
        }

        public bool CanDeleteSelectedResults()
        {
            return
                MessageBox.Show("Delete selected Test Run History items?", "Delete Items", MessageBoxButtons.YesNo,
                                MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes;
        }

        public void DisplayInvalidResultsFileMessage()
        {
            MessageBox.Show(
                "The selected file is not a valid test results file.",
                "Invalid File Format",
                MessageBoxButtons.OK,
                MessageBoxIcon.Warning);
        }

        public string TestFile { get; set; }

        public void SubscribeLoadTestFileRequested(EventHandler listener)
        {
            _loadTestFileRequested = listener;
        }

        public void SetDataSources(List<DataSourceInfo> sources)
        {
            mnuTestViewDataSource.DropDown.Items.Clear();
            if (sources == null)
            {
                // Nothing to do.
            }
            else
            {
                foreach (var item in sources)
                {
                    // Populate Test->View Data Source menu
                    var menuItem = new ToolStripMenuItem(item.ConnectionStringName, null,
                                                         new EventHandler(ViewDataSource_Click), item.Name);
                    mnuTestViewDataSource.DropDown.Items.Add(menuItem);
                }
            }
            mnuTestViewDataSource.Enabled = mnuTestViewDataSource.DropDown.Items.Count > 0;
            UpdateOptions();
        }

        public void SubscribeDataSourceSelected(EventHandler<GenericEventArgs<string>> listener)
        {
            _dataSourceSelectedListener = listener;
        }

        public void SubscribeCopyTestResultsToClipBoard(EventHandler listener)
        {
            _copyTestResultsToClipBoard = listener;
        }

        #endregion

        #region ITestRunnerView Members

        public void SetRootDataContext(object context)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}